package hadoop;

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
    // LongWritable, Text分别表示 每一行文本的偏移量 + 每一行文本的内容，为Mapper函数的输入
    // 后面的Text, IntWritable分别表示经过Mapper处理后，返回的每一个单词的出现频率
    // Text表示单词，IntWritable表示出现频率

    // 考虑到后面要重复统计每一行，很多个单词，所以先声明两个属性用于记录
    // 如果放到重写的Mapper方法体中的话，数据量过大就会造成内存空间的浪费

    // Text是Hadoop中的比肩Java-String的数据结构,这里的k用来保存单词
    Text k = new Text();
    IntWritable v = new IntWritable(1);
    // 用来保存每个单词出现的次数，因为每个单词都直接统计为1，同样为了避免重复定义，直接声明为类的属性。

    // 重写Mapper类中的map方法，里面封装了对每一行的处理逻辑，Mapper会重复调用这个函数
    // LongWritable key是该行的文本偏移量、Text value是该行的文本、
    // Context context用于暂时存储 map() 处理后的结果
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{

        // 1.传入的行的数据类型为Text，先将其转换为String
        String line = value.toString();

        // 2.对这行进行切割，分隔符使用空格“ ”,输出结果保存到字符串类型的数组words中
        String[] words = line.split(" ");

        // 3.输出结果
        for (String word : words){
            k.set(word); // 将这个单词（String类型）转换为Text类型，保存为k
            context.write(k, v); // 记录该单词，词频为1
            System.out.println(k+","+v);
        }
    }
}








// 举例，某一行为 String String java
// 输出到context中的内容就是：
// (String, 1) (String, 1) (java, 1)